package com.example.demo.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.util.ResultUtil;
import com.example.demo.common.util.entity.Result;
import com.example.demo.common.util.entity.ResultEnum;
import com.example.demo.common.util.entity.SysResultEnum;
import com.example.demo.modules.sys.dto.dict.QueryDTO;
import com.example.demo.modules.sys.dto.dict.SaveOrUpdateDTO;
import com.example.demo.modules.sys.entity.Dict;
import com.example.demo.modules.sys.dao.DictMapper;
import com.example.demo.modules.sys.service.IDictService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 字典 服务实现类
 * </p>
 *
 * @author lmy
 * @since 2023-01-29
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements IDictService {

//    List<String> pathList = new ArrayList<>();

    @Override
    public IPage<Dict> listDict(Page page, QueryDTO queryDTO) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(queryDTO.getId())){
            queryWrapper.lambda().eq(Dict::getParentId, queryDTO.getId());
        }else{
            queryWrapper.lambda().isNull(Dict::getParentId);
        }
        queryWrapper.lambda().like(StringUtils.isNotEmpty(queryDTO.getType()), Dict::getType, queryDTO.getType())
                .orderByAsc(Dict::getType);
        IPage iPage = this.baseMapper.selectPage(page, queryWrapper);
        return iPage;
    }

    @Override
    public ResultEnum saveDict(SaveOrUpdateDTO saveOrUpdateDTO) {
        Dict dict = new Dict();
        BeanUtils.copyProperties(saveOrUpdateDTO, dict);
        if(StringUtils.isNotEmpty(dict.getParentId())){
            Dict parentDict = this.getById(dict.getParentId());
            if(Objects.isNull(parentDict)){
                return SysResultEnum.PARENT_DICT_NOT_EXIST;
            }
            dict.setType(parentDict.getType());
            //值、名称重复性校验(在父项范围下)
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Dict::getParentId, dict.getParentId()).eq(Dict::getValue, dict.getValue());
            int count1 = this.count(queryWrapper);
            if(count1 > 0){
                return SysResultEnum.DICT_VALUE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().eq(Dict::getParentId, dict.getParentId()).eq(Dict::getName, dict.getName());
            int count2 = this.count(queryWrapper);
            if(count2 > 0){
                return SysResultEnum.DICT_NAME_REPEAT;
            }
        }else{
            //类型、值、名称重复性校验(所有顶层值之间比较)
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getType, dict.getType());
            int count1 = this.count(queryWrapper);
            if(count1 > 0){
                return SysResultEnum.DICT_TYPE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getValue, dict.getValue());
            int count2 = this.count(queryWrapper);
            if(count2 > 0){
                return SysResultEnum.DICT_VALUE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getName, dict.getName());
            int count3 = this.count(queryWrapper);
            if(count3 > 0){
                return SysResultEnum.DICT_NAME_REPEAT;
            }
        }
        this.save(dict);
        updateLevelAndPathAndChildrenNum(dict.getId());
        return ResultEnum.SUCCESS;
    }

    @Override
    public ResultEnum updateDict(SaveOrUpdateDTO saveOrUpdateDTO) {
        Dict oldDict = this.getById(saveOrUpdateDTO.getId());
        Dict dict = new Dict();
        BeanUtils.copyProperties(saveOrUpdateDTO, dict);
        if(StringUtils.isNotEmpty(oldDict.getParentId())){
            Dict parentDict = this.getById(oldDict.getParentId());
            if(Objects.isNull(parentDict)){
                return SysResultEnum.PARENT_DICT_NOT_EXIST;
            }
            dict.setType(parentDict.getType());
            //值、名称重复性校验(在父项范围下)
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Dict::getParentId, oldDict.getParentId()).eq(Dict::getValue, dict.getValue());
            int count1 = this.count(queryWrapper);
            if(count1 > 0){
                return SysResultEnum.DICT_VALUE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().eq(Dict::getParentId, oldDict.getParentId()).eq(Dict::getName, dict.getName());
            int count2 = this.count(queryWrapper);
            if(count2 > 0){
                return SysResultEnum.DICT_NAME_REPEAT;
            }
        }else{
            //类型、值、名称重复性校验(所有顶层值之间比较)
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getType, dict.getType());
            int count1 = this.count(queryWrapper);
            if(count1 > 0){
                return SysResultEnum.DICT_TYPE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getValue, dict.getValue());
            int count2 = this.count(queryWrapper);
            if(count2 > 0){
                return SysResultEnum.DICT_VALUE_REPEAT;
            }
            queryWrapper.clear();
            queryWrapper.lambda().isNull(Dict::getParentId).eq(Dict::getName, dict.getName());
            int count3 = this.count(queryWrapper);
            if(count3 > 0) {
                return SysResultEnum.DICT_NAME_REPEAT;
            }
        }
        this.updateById(dict);
        updateLevelAndPathAndChildrenNum(dict.getId());
        return ResultEnum.SUCCESS;
    }

    @Override
    public ResultEnum deleteDict(String id) {
        //父项的子项总数-1
        Dict dict = this.getById(id);
        if(StringUtils.isNotEmpty(dict.getParentId())){
            Dict parentDict = this.getById(dict.getParentId());
            int num = parentDict.getChildrenNum() - 1;
            UpdateWrapper<Dict> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(Dict::getChildrenNum, num);
            this.update(updateWrapper);
        }
        this.removeById(id);
        return ResultEnum.SUCCESS;
    }

    /**
     * 修改层级、路径、父项的子项总数
     * @param id
     */
    private void updateLevelAndPathAndChildrenNum(String id){
        //修改父项的子项总数
        Dict dict = this.getById(id);
        if(StringUtils.isNotEmpty(dict.getParentId())){
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Dict::getParentId, dict.getParentId());
            int count = this.count(queryWrapper);
            UpdateWrapper<Dict> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(Dict::getChildrenNum, count).eq(Dict::getId, dict.getParentId());
            this.update(updateWrapper);
        }
        //修改本项层级
        UpdateWrapper<Dict> updateWrapper1 = new UpdateWrapper<>();
        if(StringUtils.isNotEmpty(dict.getParentId())){
            //得到父项层级
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Dict::getId, dict.getParentId());
            Dict parentDict = this.getOne(queryWrapper);
            int level = parentDict.getLevel() + 1;
            updateWrapper1.lambda().set(Dict::getLevel, level).eq(Dict::getId, id);
            this.update(updateWrapper1);
        }
        //修改本项path路径
        if(StringUtils.isEmpty(dict.getParentId())){
            UpdateWrapper<Dict> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(Dict::getLevel, 0).set(Dict::getPath, dict.getId()).eq(Dict::getPath, dict.getId());
            this.update(updateWrapper);
        }else{
            List<String> list = new ArrayList<>();
            recursionForPath(id, list);
            if(CollectionUtils.isNotEmpty(list)){
                Collections.reverse(list);
                UpdateWrapper<Dict> updateWrapper2 = new UpdateWrapper<>();
                updateWrapper2.lambda().set(Dict::getPath, StringUtils.join(list, ",")).eq(Dict::getId, id);
                this.update(updateWrapper2);
            }
        }
    }

    /**
     * 递归获取字典路径
     * @return
     */
    private List<String> recursionForPath(String id, List<String> organList){
        Dict dict = this.getById(id);
        if(Objects.isNull(dict)){
            return organList;
        }
        organList.add(id);
        //递归直到顶层
        if(StringUtils.isNotEmpty(dict.getParentId())){
            return recursionForPath(dict.getParentId(), organList);
        }else{
            return organList;
        }
    }

}
